﻿#include "zip.h"
#include "private/qzipreader_p.h"
#include "private/qzipwriter_p.h"
#include <QDir>
#include <QFileInfo>
#include <QtConcurrent/QtConcurrent>
#include "tools.h"

ZipResponse *Zip::compressAsync(const QString &dir, const QString &zipPath)
{
    ZipResponse * response = new ZipResponse();
    QtConcurrent::run([=](){
        QStringList list;
        Tools::findAllfile(dir,list);

        int i=1;
        auto total = list.size();
        QDir root(dir);
        QZipWriter *writer = new QZipWriter(zipPath);
        bool isSucceed=true;
        QString msg;
        foreach(auto path,list){
            auto relativePath = root.relativeFilePath(path);
            QFile file(path);
            if(!file.exists())
                continue;
            if(!file.open(QIODevice::ReadOnly)){
                msg = QString(u8"打开 %1 失败").arg(relativePath);
                isSucceed=false;
                break;
            }
            writer->addFile(relativePath,file.readAll());
            file.close();
            emit response->progress(i++,total);
        }

        writer->close();
        emit response->finished(isSucceed,msg);
    });
    return response;
}

ZipResponse *Zip::compressAsync(const QString &rootDir, const QStringList &files, const QString &zipPath)
{
    ZipResponse * response = new ZipResponse();
    QtConcurrent::run([=](){
        int i=1;
        auto total = files.size();
        QDir root(rootDir);
        QZipWriter *writer = new QZipWriter(zipPath);
        bool isSucceed=true;
        QString msg;
        foreach(auto path,files){
            auto relativePath = root.relativeFilePath(path);
            QFile file(path);
            if(!file.exists()){
                emit response->progress(i++,total);
                continue;
            }
            if(!file.open(QIODevice::ReadOnly)){
                msg = QString(u8"打开 %1 失败").arg(relativePath);
                isSucceed=false;
                break;
            }
            writer->addFile(relativePath,file.readAll());
            file.close();
            emit response->progress(i++,total);
        }

        writer->close();
        emit response->finished(isSucceed,msg);
    });
    return response;
}

ZipResponse *Zip::decompressionAsync(const QString &zipPath, const QString &dir)
{
    ZipResponse * response = new ZipResponse();
    QtConcurrent::run([=](){
        int i=1;
        QString msg;
        QDir root(dir);
        bool isSucceed=true;
        QZipReader reader(zipPath);
        auto count = reader.count();

        Tools::mkMutiDir(QDir::fromNativeSeparators(dir));

        foreach(auto fileInfo, reader.fileInfoList()) {
            if(fileInfo.isFile){
                auto absolutePath = root.absoluteFilePath(fileInfo.filePath);
                QFileInfo absolutePathFileInfo(absolutePath);
                QDir filedir(absolutePathFileInfo.dir().path());
                Tools::mkMutiDir(filedir.path());
                QFile file(absolutePath);
                if(!file.open(QIODevice::WriteOnly)){
                    msg = QString(u8"打开 %1 失败").arg(absolutePath);
                    isSucceed=false;
                    break;
                }
                auto data = reader.fileData(fileInfo.filePath);
                if(data.size() != fileInfo.size)
                {
                    auto utf8 = fileInfo.filePath.toUtf8();
                    auto local8Bit = QString::fromLocal8Bit(utf8);
                    data = reader.fileData(local8Bit);
                    if(data.size() != fileInfo.size){
                        file.close();
                        msg = QString(u8"解压 %1 失败!").arg(fileInfo.filePath);
                        isSucceed=false;
                        break;
                    }
                }
                file.write(data);
                file.close();
            }
            emit response->progress(i++,count);
        }
        reader.close();
        emit response->finished(isSucceed,msg);
    });
    return  response;
}
